/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Copyright (C) 2021-2022 OpenFOAM Foundation
     \\/     M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

Class
    Foam::patchToPatches::intersection

Description
    Class to generate patchToPatch coupling geometry. Coupling is determined by
    means of comparing the bound boxes generated by the intersection method.
    This generates an outer "envelope" of possible intersections that can be
    used for ray shooting and Lagrangian transfer.

    Note that this method is not added to the run-time selection table, as it
    is not a method which facilitates patch coupling or mapping.

SourceFiles
    rays.C

\*---------------------------------------------------------------------------*/

#ifndef raysPatchToPatch_H
#define raysPatchToPatch_H

#include "patchToPatch.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{
namespace patchToPatches
{

/*---------------------------------------------------------------------------*\
                          Class rays Declaration
\*---------------------------------------------------------------------------*/

class rays
:
    public patchToPatch
{
    // Private Data

        // Parallel

            //- Cache of the part of the source patch local to the target
            autoPtr<PrimitiveOldTimePatch<faceList, pointField>>
                localSrcPatchPtr_;

            //- Cache of the part of the target patch local to the source
            autoPtr<PrimitiveOldTimePatch<faceList, pointField>>
                localTgtPatchPtr_;


    // Private Member Functions

        //- Get the bound box for a source face
        virtual treeBoundBox srcBox
        (
            const face& srcFace,
            const pointField& srcPoints,
            const vectorField& srcPointNormals
        ) const;

        //- Intersect two faces
        virtual bool intersectFaces
        (
            const primitiveOldTimePatch& srcPatch,
            const vectorField& srcPointNormals,
            const vectorField& srcPointNormals0,
            const primitiveOldTimePatch& tgtPatch,
            const label srcFacei,
            const label tgtFacei
        );

        //- Finalise the intersection locally. Trims the local target patch
        //  so that only parts that actually intersect the source remain.
        //  Returns new-to-old map for trimming target-associated data.
        virtual labelList finaliseLocal
        (
            const primitiveOldTimePatch& srcPatch,
            const vectorField& srcPointNormals,
            const vectorField& srcPointNormals0,
            const primitiveOldTimePatch& tgtPatch
        );

        //- Distribute the source patch so that any information needed by
        //  the target is locally available
        virtual void distributeSrc(const primitiveOldTimePatch& srcPatch);

        //- Finalising
        virtual label finalise
        (
            const primitiveOldTimePatch& srcPatch,
            const vectorField& srcPointNormals,
            const vectorField& srcPointNormals0,
            const primitiveOldTimePatch& tgtPatch,
            const transformer& tgtToSrc
        );

        //- Compute a ray intersection
        remote ray
        (
            const primitiveOldTimePatch& outPatch,
            const autoPtr<PrimitiveOldTimePatch<faceList, pointField>>&
                localOutPatchPtr,
            const autoPtr<List<remote>>& localOutProcFacesPtr,
            const List<DynamicList<label>>& inLocalOutFacesPtr,
            const scalar fraction,
            const label inFacei,
            const point& inP,
            const vector& inN,
            point& outP
        ) const;

        //- For each source face, the coupled target weights
        virtual tmpNrc<List<DynamicList<scalar>>> srcWeights() const;

        //- For each target face, the coupled source weights
        virtual tmpNrc<List<DynamicList<scalar>>> tgtWeights() const;


public:

    //- Runtime type information
    TypeName("rays");


    // Constructors

        //- Construct from components
        rays(const bool reverse);


    //- Destructor
    ~rays();


    // Member Functions

        //- Compute a ray intersection from the source side to the target
        remote srcToTgtRay
        (
            const primitiveOldTimePatch& tgtPatch,
            const scalar fraction,
            const label srcFacei,
            const vector& srcP,
            const vector& srcN,
            point& tgtP
        ) const;

        //- Compute a ray intersection from the target side to the source
        remote tgtToSrcRay
        (
            const primitiveOldTimePatch& srcPatch,
            const scalar fraction,
            const label tgtFacei,
            const vector& tgtP,
            const vector& tgtN,
            point& srcP
        ) const;
};


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace patchToPatches
} // End namespace Foam

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //
